package pl.radical.open.gg.packet.handlers;
import pl.radical.open.gg.GGException;
import pl.radical.open.gg.packet.IncomingPacket;
import pl.radical.open.gg.utils.GGUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang3.ClassUtils;
import org.reflections.Configuration;
import org.reflections.Reflections;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import de.huxhorn.lilith.slf4j.Logger;
import de.huxhorn.lilith.slf4j.LoggerFactory;
/**
* Created on 2004-11-27
*
* @author <a href="mailto:mati@sz.home.pl">Mateusz Szczap</a>
* @author <a href="mailto:lukasz.rzanek@radical.com.pl>�?ukasz Rżanek</a>
*/
public class PacketChain {
private static final Logger LOG = LoggerFactory.getLogger(PacketChain.class);
private final Map<Integer, PacketHandler> packetHandlers = new HashMap<Integer, PacketHandler>();
public PacketChain() throws GGException {
registerDefaultHandlers();
}
public void registerGGPackageHandler(final int packetType, final PacketHandler packetHandler) {
if (packetHandler == null) {
throw new IllegalArgumentException("packetHandler cannot be null");
}
packetHandlers.put(Integer.valueOf(packetType), packetHandler);
}
public void registerGGPackageHandler(final int packetType, final Class<?> packetHandler) throws GGException {
if (packetHandler == null) {
throw new IllegalArgumentException("packetHandler cannot be null");
}
try {
packetHandlers.put(Integer.valueOf(packetType), (PacketHandler) packetHandler.newInstance());
} catch (final InstantiationException e) {
LOG.error("Unable to create an object of type {}", packetHandler.getClass().getName(), e);
throw new GGException("Unable to create an object of type " + packetHandler.getClass().getName(), e);
} catch (final IllegalAccessException e) {
LOG.error("Inproper use of object.newInstance()", e);
throw new GGException("Inproper use of object.newInstance()", e);
}
}
public void sendToChain(final PacketContext packageContent) throws GGException {
final PacketHandler packetHandler = packetHandlers.get(Integer.valueOf(packageContent.getHeader().getType()));
if (packetHandler == null) {
LOG.warn("Unknown package.");
LOG.warn("PacketHeader: " + packageContent.getHeader());
LOG.warn("PacketBody: " + GGUtils.prettyBytesToString(packageContent.getPackageContent()));
return;
}
packetHandler.handle(packageContent);
}
protected final void registerDefaultHandlers() throws GGException {
final Configuration configuration = new ConfigurationBuilder().setScanners(new TypeAnnotationsScanner()).setUrls(
ClasspathHelper.getUrlsForPackagePrefix("pl.radical.open.gg.packet.in"));
final Reflections reflections = new Reflections(configuration);
final Set<Class<?>> classes = reflections.getTypesAnnotatedWith(IncomingPacket.class);
if (classes.isEmpty()) {
throw new GGException("No classes found to register as packet handlers!");
}
for (final Class<?> c : classes) {
final IncomingPacket annotation = c.getAnnotation(IncomingPacket.class);
if (LOG.isTraceEnabled()) {
LOG.trace("Registering class {} with handler {} for packet [{}]", ClassUtils.getShortClassName(c.getName()), ClassUtils
.getShortClassName(annotation.handler().getName()), Integer.toString(c.getAnnotation(IncomingPacket.class).type()));
}
registerGGPackageHandler(annotation.type(), annotation.handler());
}
}
}